/* *********************************************
 * Crypto libary : Vigenere module
 * Christiaan Rakowski 20110824
 * This module will perform a basic Vigenere cipher on the input string
 * ********************************************/

using System;

namespace CryptoCs
{
	namespace Ciphers
	{
		public class Vigenere
		{
			#region Vigenere Table
			private static readonly Char[,] Table = {
			{ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' },
			{ 'B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A' },
			{ 'C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B' },
			{ 'D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C' },
			{ 'E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D' },
			{ 'F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E' },
			{ 'G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F' },
			{ 'H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G' },
			{ 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H' },
			{ 'J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I' },
			{ 'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J' },
			{ 'L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K' },
			{ 'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L' },
			{ 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M' },
			{ 'O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N' },
			{ 'P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O' },
			{ 'Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P' },
			{ 'R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q' },
			{ 'S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R' },
			{ 'T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S' },
			{ 'U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T' },
			{ 'V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U' },
			{ 'W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V' },
			{ 'X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W' },
			{ 'Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X' },
			{ 'Z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y' } };
			#endregion
			public static String Encripher(String input, String key)
			{
				String result = "";
				input = input.ToUpper();
				key = key.ToUpper();

				for (Int32 i = 0; i < input.Length; i++)
				{
					result += Encripher(input[i], key[(i % key.Length)]);
				}
				return result;
			}
			private static Char Encripher(Char input, Char key)
			{
				if (Char.IsDigit(input))
				{
					return (Char)(input ^ key);
				}
				if (Char.IsLetter(input))
				{
					Int32 i;
					for (i = 0; i < Table.GetLength(0); i++)
					{
						if (input == Table[0, i])
						{
							break;
						}
					}
					Int32 j;
					for (j = 0; j < Table.GetLength(1); j++)
					{
						if (key == Table[j, 0])
						{
							break;
						}
					}
					return Table[i, j];
				}
				return input;
			}
			public static String Decipher(String input, String key)
			{
				String result = "";
				input = input.ToUpper();
				key = key.ToUpper();

				for (Int32 i = 0; i < input.Length; i++)
				{
					result += Decipher(input[i], key[(i % key.Length)]);
				}
				return result;
			}
			private static Char Decipher(Char input, Char key)
			{
				if (Char.IsDigit(input))
				{
					return (Char)(input ^ key);
				}
				if (Char.IsLetter(input))
				{
					Int32 i;
					for (i = 0; i < Table.GetLength(0); i++)
					{
						if (key == Table[0, i])
						{
							break;
						}
					}
					Int32 j;
					for (j = 0; j < Table.GetLength(1); j++)
					{
						if (input == Table[j, i])
						{
							break;
						}
					}
					return Table[j, 0];
				}
				return input;
			}
		}
	}
}
